package cn.com.lms.business.course.service;

import cn.com.lms.business.core.constant.CourseTypeEnum;
import cn.com.lms.business.core.constant.BNZConstants;
import cn.com.lms.business.core.constant.SortEnum;
import cn.com.lms.business.core.util.SystemUserUtil;
import cn.com.lms.business.course.persistence.entity.FbCourseInfo;
import cn.com.lms.business.course.persistence.entity.vo.CourseInfoVo;
import cn.com.lms.business.course.persistence.repository.FbCourseInfoRepository;
import cn.com.lms.business.learning.persistence.repository.LearningStudentRepository;
import cn.com.lms.business.livecourse.persistence.repository.CourseLiveSignRepository;
import cn.com.lms.business.livecourse.service.CourseChatRoomService;
import cn.com.lms.business.livecourse.service.CourseLiveService;
import cn.com.lms.business.livecourse.util.CourseTypeUtil;
import cn.com.lms.business.user.persistence.entity.SysUserVo;
import com.bnzj.core.persistence.BaseService;
import com.bnzj.core.persistence.query.CompareExpression;
import com.bnzj.core.persistence.query.CompareType;
import com.bnzj.core.persistence.query.IExpression;
import com.bnzj.core.persistence.query.QueryHelpBean;
import com.bnzj.core.rest.ResponseResult;
import com.bnzj.core.webmvc.util.WebMvcUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class FbCourseInfoService extends BaseService<FbCourseInfoRepository, FbCourseInfo, Long> {

    @Autowired
    CourseLiveService courseLiveService;

    @Autowired
    CourseChatRoomService courseChatRoomService;

    @Autowired
    LearningStudentRepository studentRepository;

    @Autowired
    private CourseLiveSignRepository liveSignRepository;


    /**
     * 查询课程分页数据
     *
     * @param request
     * @param title
     * @return
     */
    public ResponseResult<Page<FbCourseInfo>> queryCourseListPage(HttpServletRequest request, String title, String categoryId, String recommendSort,
                                                                  String scoreSort, String timeSort, String liveStartTime, String courseTypeId) {
        List<Sort.Order> orderList = new ArrayList<>();
        //排序条件判断
        if (SortEnum.SORT_DESC.getValue().equals(recommendSort)) {
            orderList.add(Sort.Order.desc("recommend_num"));
        }
        if (SortEnum.SORT_ASC.getValue().equals(recommendSort)) {
            orderList.add(Sort.Order.asc("recommend_num"));
        }
        if (SortEnum.SORT_DESC.getValue().equals(scoreSort)) {
            orderList.add(Sort.Order.desc("score"));
        }
        if (SortEnum.SORT_ASC.getValue().equals(scoreSort)) {
            orderList.add(Sort.Order.asc("score"));
        }


        if (SortEnum.SORT_DESC.getValue().equals(timeSort)) {
            orderList.add(Sort.Order.desc("create_time"));
        } else if (SortEnum.SORT_ASC.getValue().equals(timeSort)) {
            orderList.add(Sort.Order.asc("create_time"));
        }
        if (SortEnum.SORT_DESC.getValue().equals(liveStartTime)) {
            orderList.add(Sort.Order.desc("live_start_time"));
        } else if (SortEnum.SORT_ASC.getValue().equals(liveStartTime)) {
            orderList.add(Sort.Order.asc("live_start_time"));
        }
        Pageable pageable = WebMvcUtils.initPage(request, Sort.by(orderList));
        QueryHelpBean queryHelpBean = getQueryHelpBean();
        queryHelpBean.setPageable(pageable);
        if (!StringUtils.isEmpty(title)) {
            IExpression notIdsCondition = CompareExpression.build("u.title", CompareType.like, title);
            queryHelpBean.addWhere(notIdsCondition);
        }
        if (!StringUtils.isEmpty(categoryId)) {
            IExpression notIdsCondition = CompareExpression.build("u.category_id", CompareType.equal, categoryId);
            queryHelpBean.addWhere(notIdsCondition);
        }
        if (!StringUtils.isEmpty(courseTypeId)) {
            List<String> typeCode = new ArrayList<>();
            for (String str : courseTypeId.split(",")) {
                typeCode.add(str);
            }
            IExpression notIdsCondition = CompareExpression.build("u.course_type", CompareType.in, typeCode);
            queryHelpBean.addWhere(notIdsCondition);
        }
        Page<FbCourseInfo> all1 = this.findAll(queryHelpBean);
        return ResponseResult.success(all1);
    }


    /**
     * 添加课程
     *
     * @param courseInfoVo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<String> saveCourse(CourseInfoVo courseInfoVo, String courseType) throws Exception {
        boolean isModifyLiveStartTime = false;     // 是否有修改直播课程开播时间标识
        int modifyType = 1;     // 修改类型： 1新增；2修改
        String msg = "新增";
        FbCourseInfo courseInfo = new FbCourseInfo();
        SysUserVo sysUser = SystemUserUtil.getCurrentUser();
        Long courseTypeId = 0L;
        List<Map<String, Object>> mapList = getCourseTypeDictionary(BNZConstants.COURSE_TYPE_CODE);
        for (Map<String, Object> item : mapList) {
            String name = (String) item.get("name");
            if (CourseTypeEnum.OTHER.getCode().equals(courseType) && CourseTypeEnum.OTHER.getValue().equals(name)) {
                //课程类型为其它
                courseTypeId = Long.valueOf(item.get(CourseTypeEnum.OTHER.getColumn()).toString());
                break;
            }
            if (CourseTypeEnum.VIDEO.getCode().equals(courseType) && CourseTypeEnum.VIDEO.getValue().equals(name)) {
                //课程类型为视频
                courseTypeId = Long.valueOf(item.get(CourseTypeEnum.VIDEO.getColumn()).toString());
                break;
            }
            if (CourseTypeEnum.LIVE.getCode().equals(courseType) && CourseTypeEnum.LIVE.getValue().equals(name)) {
                //课程类型为直播
                courseTypeId = Long.valueOf(item.get(CourseTypeEnum.LIVE.getColumn()).toString());
                if (null == courseInfoVo.getLiveStartTime() || 0 == courseInfoVo.getLivePersonId()) {
                    return ResponseResult.failure(0, "直播时间或直播人不能为空");
                }
                break;
            }
        }

        if (null != courseInfoVo.getId() && 0L != courseInfoVo.getId()) {
            courseInfo = this.repository.getOne(courseInfoVo.getId());
            msg = "修改";
            modifyType = 2;
            if (null != courseInfoVo.getLiveStartTime()) {
                isModifyLiveStartTime = courseInfo.getLiveStartTime().getTime() != courseInfoVo.getLiveStartTime().getTime();
            }
            courseInfo.setModifyTime(Timestamp.valueOf(LocalDateTime.now()));
            courseInfo.setModifyName(sysUser.getCname());
            courseInfo.setModifyBy(sysUser.getId());
        } else {
            courseInfo.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
            courseInfo.setModifyTime(Timestamp.valueOf(LocalDateTime.now()));
            courseInfo.setModifyName(sysUser.getCname());
            courseInfo.setModifyBy(sysUser.getId());
            courseInfo.setCreatorName(sysUser.getCname());
            courseInfo.setCreator(sysUser.getId());
            courseInfo.setLiveStatus(0);
        }
        BeanUtils.copyProperties(courseInfoVo, courseInfo);
        courseInfo.setCourseType(courseTypeId);
        courseInfo.setIsDelete(BNZConstants.DB_NO_DELETE);
        courseInfo.setIsOver(BNZConstants.DB_NO_OVER);
        this.repository.save(courseInfo);

        // 直播课程新增时，直播信息相关处理
        if (1 == modifyType && null != courseInfo.getLiveStartTime() && 0 < courseInfo.getId()) {
            courseLiveService.handleLiveInfoWhenCourseSave(courseInfo);

            // 直播课程修改时，直播信息相关处理
        } else {
            // 修改开播时间的相关直播信息处理
            if (isModifyLiveStartTime) {
                courseLiveService.handleLiveInfoWhenCourseUpdateLiveTime(courseInfo);
            }
        }
        return ResponseResult.success(msg + "成功");
    }


    /*
     * @author liuwei
     * @date 2020/3/16 18:23
     * @desc 删除课程信息
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult delCourse(Long id) throws Exception {
        // 指定课程类型 直播
        List<Map<String, Object>> mapList = getCourseTypeDictionary(BNZConstants.COURSE_TYPE_CODE);
        long courseTypeLiveId = CourseTypeUtil.getCourseTypeId(mapList,
                CourseTypeEnum.LIVE.getValue());
        // 直播课程删除时处理
        Optional<FbCourseInfo> optional = this.findById(id);
        FbCourseInfo courseInfo = optional.get();
        if (null != courseInfo && courseTypeLiveId == courseInfo.getCourseType()) {
            // 删除对应课程占用的聊天室
            courseChatRoomService.destroyCourseChatRoom(id);
        }
        this.repository.updateCourseStatus(id);
        return ResponseResult.success();
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseResult overCourse(Long id) {
        if (!"0".equals(getIsOverById(id))) {
            return ResponseResult.success("已是看完课程");
        }
        this.repository.updateCourseOver(id);
        return ResponseResult.success();
    }

    /*
     * @author liuwei
     * @date 2020/3/16 18:23
     * @desc 获取课程类型
     */
    public List<Map<String, Object>> getCourseTypeDictionary(String code) {
        List<Map<String, Object>> dictionaryList = this.repository.queryDictionaryList(code);
        return dictionaryList;
    }


    /*
     * @author liuwei
     * @date 2020/3/23 10:49
     * @desc APP获取我的课程列表
     */
    public ResponseResult queryCourseListByUser(HttpServletRequest request) {
        Pageable pageable = WebMvcUtils.initPage(request, Sort.by(Sort.Direction.DESC, "create_time"));
        SysUserVo user = SystemUserUtil.getCurrentUser();
        String title = request.getParameter("title");
        String courseTypeId = request.getParameter("courseTypeId");
        QueryHelpBean queryHelpBean = getQueryMyCourseInfBean(user.getId());
        IExpression notIdsCondition = CompareExpression.build("ci.title", CompareType.like, title);

        IExpression courseTypeIdCondition = CompareExpression.build("ci.course_type", CompareType.equal, courseTypeId);
        queryHelpBean.addWhere(notIdsCondition);
        queryHelpBean.addWhere(courseTypeIdCondition);
        queryHelpBean.setPageable(pageable);
        Page<Map<String, Object>> all1 = this.findAll(queryHelpBean);
        return ResponseResult.success(all1);
    }

    /*
     * @author liuwei
     * @date 2020/3/23 14:41
     * @desc 修改课程学时信息
     */
    @Transactional
    public ResponseResult updateCourse(Long detailId, Integer learningHours) {
        studentRepository.updateLearningHours(new Date(), learningHours, detailId, SystemUserUtil.getCurrentUser().getId());
        return ResponseResult.success();
    }

    /*
     * @author liuwei
     * @date 2020/3/23 11:29
     * @desc //课程详情
     */
    public ResponseResult getCourseView(Long courseId) {
        FbCourseInfo courseInfo = null;
        try {
            courseInfo = this.repository.getOne(courseId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseResult.success(courseInfo);
    }

    /**
     * 获取配置项数据
     *
     * @param key
     * @return
     */
    public String getSysSettingValue(String key) {
        return liveSignRepository.sysSettingValue(key);
    }


    public QueryHelpBean getQueryHelpBean() {
        String selectSQL = " SELECT u.id,u.title,su.cname ,u.course_type,d.name as course_type_name,u.course_time,u.recommend_num,u.score,u.credit,u.live_status," +
                "u.remark,u.picture_url,u.course_file,u.category_id,u.create_time,u.modify_time,(CASE when u.live_status=0 then u.live_start_time else u.live_real_start_time end ) live_start_time ,u.live_person_id,u.creator_name,'10' as stuNum," +
                "(select count(lsd.id)from bnz_learning_stage_detail lsd where lsd.obj_id=u.id and lsd.study_type=0) isJoin ";
        String whereSQL = " FROM  bnz_course_info u left join bnz_sys_dictionary d on u.course_type=d.id  left join bnz_sys_user su on su.id=u.live_person_id where u.is_delete=0 ";
        QueryHelpBean queryBean = new QueryHelpBean(selectSQL + whereSQL, "select count(1)" + whereSQL);
        return queryBean;
    }


    public QueryHelpBean getQueryMyCourseInfBean(Long userId) {
        String selectSQL = " select a.*,ci.id,ci.title,ci.picture_url,ci.course_type,d.`name` AS courseTypeName,ci.course_time,ci.live_status,ci.live_start_time,ci.live_real_start_time liveRealStartTime,ci.create_time";
        String whereSQL = " from (select ls.id detailId,ls.stage_detail_id stageDetailId,ld.obj_id,ld.stage_id,ld.plan_id,(select plan_name from bnz_learning_plan where id =ld.plan_id) planName,ls.last_study_time,ls.finish_state,ls.learning_hours from bnz_learning_student ls" +
                " inner join  bnz_learning_stage_detail ld on ld.id=ls.stage_detail_id " +
                " where study_type= 0 and ls.user_id=" + userId +
                " ) a INNER JOIN bnz_course_info ci on ci.id=a.obj_id  and ci.is_delete=0 left join bnz_sys_dictionary d on ci.course_type=d.id where ci.is_delete=0";
        QueryHelpBean queryBean = new QueryHelpBean(selectSQL + whereSQL, "select count(1)" + whereSQL);
        return queryBean;
    }


    public List<FbCourseInfo> findByCategoryId(Long id) {
        return repository.findByCategoryId(id);
    }

    public List<FbCourseInfo> getCourseListByGroupId(String groupId) {
        return repository.findByGroupId(groupId);
    }

    public String getgetUrlById(Long courseId){
        return repository.getUrl(courseId);
    }

    public String getIsOverById(Long courseId){
        return repository.getIsOver(courseId);
    }






}
